# 底层
import time

# 通信
import paho.mqtt.client as mqtt
from urllib.parse import quote
import base64
import requests
import hmac
import json


class Device:
    def __init__(self):
        self.client = self.client_create()
        self.client.connect("studio-mqtt.heclouds.com", 1883)
        self.client.on_connect = self.on_connect
        self.client.on_message = self.on_message
        self.client.on_publish = self.on_publish
        self.client.on_subscribe = self.on_subscribe
        self.client.connect('studio-mqtt.heclouds.com', 1883, 60)

        self.client.subscribe("$sys/yuh3mf40BP/client/thing/property/set")

    # ----------------------设备接入--------------
    @staticmethod
    def getToken():  # 获取Token鉴权
        et = ''.join(str(int(time.time() + 6000)))
        method = 'md5'
        res = 'products/yuh3mf40BP/devices/client'
        version = '2018-10-31'
        key = base64.b64decode('E2d9u8MfecGfu70PbecpI+HB+dEhOd3x4achY4txP/k=')
        StringForSignature = et + '\n' + method + '\n' + res + '\n' + version

        sign_b = hmac.new(key, StringForSignature.encode(), digestmod='MD5')  # 签名算法
        sign = base64.b64encode(sign_b.digest()).decode()

        sign = quote(sign)  # 转为url格式
        res = quote(res, safe='')

        token = 'version={0}&' \
                'res={1}&' \
                'et={2}&' \
                'method={3}&' \
                'sign={4}' \
            .format(version, res, et, method, sign)
        return token

    def client_create(self):
        username = 'yuh3mf40BP'
        client_id = 'client'
        client = mqtt.Client(client_id=client_id, protocol=mqtt.MQTTv311)
        client.username_pw_set(username=username, password=self.getToken())
        return client

    @staticmethod
    def on_subscribe(client, userdata, mid, granted_qos):
        print("granted_qos:", granted_qos, mid)

    @staticmethod
    def on_connect(client, userdata, flags, rc):
        print("Your connect state is {0}".format(rc))

    @staticmethod
    def on_message(client, userdata, msg):
        message = json.loads(msg.payload)
        print(message)

    @staticmethod
    def on_publish(client, userdata, mid):
        print("publish successfully")

    def post_data(self, id, value):
        payload = json.dumps({"id": str(int(time.time())),
                              "version": "1.0",
                              "params": {
                                  id: {"value": value}
                              }
                              })
        self.client.publish('$sys/yuh3mf40BP/client/thing/property/post', payload=payload)

    def get_data(self, id):
        payload = json.dumps({
            "id": str(int(time.time())),
            "version": "1.0",
            "params": [
                id
            ]
        })
        self.client.publish("$sys/yuh3mf40BP/client/thing/property/get", payload=payload)


# -----------------应用API接入----------------
class APP:
    @staticmethod
    def getAuthorization():  # 计算应用API鉴权
        version = "2020-05-29"
        res = "userid/118038"
        et = ''.join(str(int(time.time() + 6000)))
        method = "md5"
        accessKey = base64.b64decode(
            "8Wm9/12OajYN/evD/+jwy76mxBhrxfEvqKsZtjpDd0auy8/gGR4Id+0nIOullG4Mr0urBK0hDydEc38NSi327Q==")
        StringForSignature = et + '\n' + method + '\n' + res + '\n' + version

        sign_b = hmac.new(accessKey, StringForSignature.encode(), digestmod='MD5')
        sign = base64.b64encode(sign_b.digest()).decode()

        sign = quote(sign)  # 转为url格式
        res = quote(res, safe='')

        authorization = 'version={0}&' \
                        'res={1}&' \
                        'et={2}&' \
                        'method={3}&' \
                        'sign={4}' \
            .format(version, res, et, method, sign)
        return {"authorization": authorization}

    def queryDeviceData(self, identifier):
        url = "http://openapi.heclouds.com/application?action=QueryDeviceProperty&version=1"
        params = {
            "project_id": "nZ6fz3",
            "product_id": "yuh3mf40BP",
            "device_name": "client"
        }

        authorization = self.getAuthorization()

        t = requests.get(url, params=params, headers=authorization)
        try:
            lists = json.loads(t.text)["data"]["list"]
            for model in lists:
                if model["identifier"] == identifier:
                    try:
                        return model["value"], model["time"]
                    except UnboundLocalError:
                        return '', ''
        except json.decoder.JSONDecodeError:
            pass
            # print(t.text)

    def SetDeviceProperty(self, identifier, data):
        authorization = self.getAuthorization()
        url = "http://openapi.heclouds.com/application?action=SetDeviceProperty&version=1"
        data = {
            "project_id": "nZ6fz3",
            "product_id": "yuh3mf40BP",
            "device_name": "client",
            "params": {identifier: data}
        }
        print(requests.post(url, json=data, headers=authorization).text)
